home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / utility / 252 / dskpcsrc / program.mod < prev    next >
Text File  |  1988-02-13  |  22KB  |  668 lines

  1. IMPLEMENTATION MODULE Program;
  2.  
  3.  
  4.    (*$S-,$T- turn off stack and range checking *) 
  5.  
  6.    FROM SYSTEM IMPORT ADR;
  7.    IMPORT M2Conversions;
  8.    IMPORT GEMDOS;
  9.    IMPORT GEMAESbase;
  10.    IMPORT AESGraphics;
  11.    IMPORT AESForms;
  12.    IMPORT Text;
  13.    IMPORT Icon;
  14.    IMPORT Resource;
  15.    IMPORT Screen;
  16.    IMPORT Readout;
  17.    IMPORT Float;
  18.    IMPORT Keypad;
  19.    IMPORT Expression;
  20.    IMPORT Configuration;
  21.    IMPORT Print;
  22.    IMPORT FileName;
  23.    IMPORT Disk;
  24.  
  25.  
  26.    TYPE String3 = ARRAY [0..2] OF CHAR;
  27.  
  28.    CONST
  29.       DefaultFileName    = "NONAME.CAL";
  30.       MemorySize         = 500 (* steps *);
  31.       Nop                = 0;
  32.       Bell               = 07C;
  33.  
  34.       ExecuteErrorLine1  = "[3][ The Program Counter exceeds | the length of the program. |";
  35.       ExecuteErrorLine2  = " Execution has been stopped. ][ OK ]";
  36.  
  37.       FuncKeyError       = "[1][ The function key | was not found. ][ OK ]";
  38.  
  39.       FileSaveErrorLine1 = "[3][ An error occurred while | saving the program.  Make |";
  40.       FileSaveErrorLine2 = " sure that the disk is not | full or write protected. ][ OK ]";
  41.  
  42.       FileTypeError      = "[3][ The file is not a valid | calculator program file. ][ OK ]";
  43.  
  44.       FileLoadError      = "[1][ An error occurred while | loading the program. ][ OK ]";
  45.  
  46.    VAR
  47.       UpdateRegion  : Screen.Box;
  48.       EnteringSteps : BOOLEAN;
  49.       PC            : CARDINAL;  (* Program Counter *)
  50.       Memory        : ARRAY [0..MemorySize] OF INTEGER;
  51.       NumberBase    : INTEGER;
  52.       ProgramSize   : CARDINAL;
  53.       Index         : CARDINAL;
  54.       ExpectKeys    : CARDINAL;
  55.       FileSignature : String3;
  56.       Directory     : Text.String80;
  57.       FileNameBody  : Text.String80;
  58.  
  59.    (************************ LOCAL ROUTINE *****************************)
  60.  
  61.    PROCEDURE ClearMemory;
  62.  
  63.    VAR Index : CARDINAL;
  64.  
  65.    BEGIN
  66.       FOR Index := 0 TO MemorySize DO
  67.          Memory[Index] := Resource.D9STOP;
  68.       END;
  69.       ProgramSize := 1;
  70.    END ClearMemory;
  71.  
  72.    (************************ LOCAL ROUTINE *****************************)
  73.  
  74.    PROCEDURE GetStepText (
  75.       StepNumber : CARDINAL;
  76.       VAR Buffer : ARRAY OF CHAR );
  77.  
  78.    VAR
  79.       Location : Text.String80;
  80.       Success  : BOOLEAN;
  81.       Key      : INTEGER;
  82.       Object   : Icon.ObjectPtr;
  83.       TextPtr  : Text.StringPtr;
  84.       KeyLabel : Text.String80;
  85.  
  86.    BEGIN
  87.       Text.Assign ( "step ", Buffer );
  88.       M2Conversions.ConvertCardinal ( StepNumber, 3, Location );
  89.       IF Location[0] = ' ' THEN
  90.          Location[0] := '0';
  91.       END;
  92.       IF Location[1] = ' ' THEN
  93.          Location[1] := '0';
  94.       END;
  95.       Success := Text.ConcatString ( Buffer, Location, Buffer );
  96.       Success := Text.ConcatString ( Buffer, " = ", Buffer );
  97.       Key := Memory[StepNumber];
  98.       IF Key = Nop THEN
  99.          Success := Text.ConcatString ( Buffer, "Nop ", Buffer );
  100.       ELSE
  101.          Object  := Icon.GetAddress ( Resource.D9CALC, Key );
  102.          TextPtr := Text.StringPtr ( Object^.Spec );
  103.          Text.Assign ( TextPtr^, KeyLabel );
  104.          Success := Text.ConcatString ( KeyLabel, "    ", KeyLabel );
  105.          Success := Text.SliceString ( KeyLabel, 0, 3, KeyLabel );
  106.          Success := Text.ConcatString ( Buffer, KeyLabel, Buffer );
  107.       END;
  108.       Success := Text.ConcatChar ( Buffer, ' ', Buffer );
  109.    END GetStepText;
  110.  
  111.    (************************ LOCAL ROUTINE *****************************)
  112.  
  113.    PROCEDURE InsertKey ( Key : (* IN *) INTEGER );
  114.  
  115.    VAR Buffer : Text.String80;
  116.  
  117.    BEGIN
  118.       Memory[PC] := Key;
  119.       IF PC >= ProgramSize THEN
  120.          INC (ProgramSize);
  121.       END;
  122.       INC (PC);
  123.       IF PC >= MemorySize THEN
  124.          GEMDOS.ConOut ( Bell );
  125.          DEC (PC);  (* Cant exceed the memory capacity *)
  126.       ELSIF PC >= ProgramSize THEN
  127.          Memory[PC] := Nop;
  128.       END;
  129.       GetStepText ( PC, Buffer );
  130.       Readout.Write ( Buffer, UpdateRegion );
  131.    END InsertKey;
  132.  
  133.    (************************ LOCAL ROUTINE *****************************)
  134.  
  135.    PROCEDURE ExecuteProgram;
  136.  
  137.    CONST
  138.       HideKeys   = FALSE;
  139.       ShowKeys   = TRUE;
  140.       LeftButton = 0;
  141.  
  142.    VAR
  143.       Key             : INTEGER;
  144.       Number          : Text.String80;
  145.       Button          : INTEGER;
  146.       ExecuteMsg      : ARRAY [0..200] OF CHAR;
  147.       Success         : BOOLEAN;
  148.       Mouse           : Screen.PixelCoordinate;
  149.       MouseState      : INTEGER;
  150.       KeyboardState   : INTEGER;
  151.       Object          : INTEGER;
  152.       RunButton       : Icon.ObjectPtr;
  153.       StopButton      : Icon.ObjectPtr;
  154.       SavedNumberBase : INTEGER;
  155.  
  156.    BEGIN
  157.       RunButton := Icon.GetAddress ( Resource.D9CALC, Resource.D9RUN );
  158.       RunButton^.State := RunButton^.State + {Icon.Selected};
  159.       Icon.Display ( Resource.D9CALC, Resource.D9RUN, UpdateRegion );
  160.  
  161.       StopButton := Icon.GetAddress ( Resource.D9CALC, Resource.D9STOP );
  162.       StopButton^.State := StopButton^.State - {Icon.Disabled};
  163.       Icon.Display ( Resource.D9CALC, Resource.D9STOP, UpdateRegion );
  164.  
  165.       AESGraphics.GrafMouse ( GEMAESbase.HourGlass, NIL );
  166.       SavedNumberBase := NumberBase;
  167.       LOOP
  168.          IF (PC >= ProgramSize) OR (PC >= MemorySize) THEN
  169.             ExecuteMsg := ExecuteErrorLine1;
  170.             Success := Text.ConcatString ( ExecuteMsg, ExecuteErrorLine2, ExecuteMsg );
  171.             AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
  172.             Button  := AESForms.FormAlert ( 1, ExecuteMsg );
  173.             IF (PC >= MemorySize) THEN
  174.                PC := MemorySize - 1;
  175.             END;
  176.             EXIT;
  177.          ELSE
  178.             Key := Memory[PC];
  179.             INC (PC);
  180.             IF (Key = Nop) OR
  181.                (Key = Resource.D9F1) OR
  182.                (Key = Resource.D9F2) OR
  183.                (Key = Resource.D9F3) OR  
  184.                (Key = Resource.D9F4) OR
  185.                (Key = Resource.D9F5) OR
  186.                (Key = Resource.D9F6) OR
  187.                (Key = Resource.D9F7) OR
  188.                (Key = Resource.D9F8) OR
  189.                (Key = Resource.D9F9) OR
  190.                (Key = Resource.D9F10) THEN
  191.                   (* do nothing *)
  192.             ELSIF Key = Resource.D9STOP THEN
  193.                EXIT;
  194.             ELSIF NOT ProcessKey ( Key, UpdateRegion ) THEN
  195.                IF Keypad.ProcessKey (
  196.                      Key,
  197.                      UpdateRegion,
  198.                      HideKeys,
  199.                      Number ) THEN
  200.                   Expression.ProcessKey ( Key, UpdateRegion, Number );
  201.                   IF Float.Error THEN
  202.                      EXIT;  (* Abort the program *)
  203.                   END;
  204.                END; 
  205.             END;
  206.          END;
  207.          AESGraphics.GrafMouseKeyboardState (
  208.             Mouse.X, Mouse.Y, MouseState, KeyboardState );
  209.          IF (LeftButton IN BITSET (MouseState)) AND
  210.             Icon.Find ( Resource.D9CALC, Mouse, Object ) AND
  211.             (Object = Resource.D9STOP) THEN 
  212.                EXIT;  (* Abort the program *)
  213.          END;
  214.       END (* LOOP *);
  215.  
  216.       IF NumberBase <> SavedNumberBase THEN
  217.          Success := Keypad.ProcessKey (
  218.             NumberBase, UpdateRegion, ShowKeys, Number );
  219.       END;
  220.  
  221.       RunButton^.State := RunButton^.State - {Icon.Selected};
  222.       Icon.Display ( Resource.D9CALC, Resource.D9RUN, UpdateRegion );
  223.  
  224.       StopButton^.State := StopButton^.State + {Icon.Disabled};
  225.       Icon.Display ( Resource.D9CALC, Resource.D9STOP, UpdateRegion );
  226.  
  227.       AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
  228.    END ExecuteProgram;
  229.  
  230.    (************************ LOCAL ROUTINE *****************************)
  231.  
  232.    PROCEDURE SearchKey ( Key : INTEGER );
  233.  
  234.    VAR
  235.       Index  : CARDINAL;
  236.       Button : INTEGER;
  237.  
  238.    BEGIN
  239.       Index := 0;
  240.       LOOP
  241.          IF (Index >= ProgramSize) OR (Index >= MemorySize) THEN
  242.             Button := AESForms.FormAlert ( 1, FuncKeyError );
  243.             EXIT;
  244.          ELSIF Memory[Index] = Key THEN
  245.             PC := Index;
  246.             ExecuteProgram;
  247.             EXIT;
  248.          ELSE
  249.             INC (Index);
  250.          END;
  251.       END (* LOOP *);
  252.    END SearchKey;
  253.  
  254.    (************************ LOCAL ROUTINE *****************************)
  255.  
  256.    PROCEDURE SaveProgram;
  257.  
  258.    CONST
  259.       Ok         = 1;
  260.       NormalFile = 0;
  261.  
  262.    VAR
  263.       FullFileName  : Text.String80;
  264.       ExitButton    : INTEGER;
  265.       FileHandle    : INTEGER;
  266.       FileStatus    : INTEGER;
  267.       Count         : LONGCARD;
  268.       Success       : BOOLEAN;
  269.       FileSaveError : ARRAY [0..200] OF CHAR;
  270.  
  271.    BEGIN
  272.       FileStatus := GEMDOS.EOK;
  273.       AESForms.FileSelectorInput (
  274.          ADR (Directory), ADR (FileNameBody), ExitButton );
  275.       Text.UpperCase ( Directory );
  276.       IF (ExitButton = Ok) AND (Text.Length (FileNameBody) > 0) THEN
  277.          FileName.BuildFileName ( Directory, FileNameBody, FullFileName );
  278.          IF FullFileName[1] = ':' THEN
  279.             Disk.CheckStatus ( ORD (FullFileName[0]) - ORD ('A') + 1 );
  280.          END;
  281.          GEMDOS.Create ( FullFileName, NormalFile, FileHandle );
  282.          IF FileHandle < GEMDOS.EOK THEN
  283.             FileStatus := FileHandle;
  284.          ELSE
  285.             FileStatus := GEMDOS.EWritF;
  286.             Count := LONGCARD (SIZE (FileSignature));
  287.             GEMDOS.Write ( FileHandle, Count, ADR (FileSignature) );
  288.             IF Count = LONGCARD (SIZE (FileSignature)) THEN
  289.                Count := LONGCARD (SIZE (ProgramSize));
  290.                GEMDOS.Write ( FileHandle, Count, ADR (ProgramSize) );
  291.                IF Count = LONGCARD (SIZE (ProgramSize)) THEN
  292.                   Count := LONGCARD (SIZE (Memory));
  293.                   GEMDOS.Write ( FileHandle, Count, ADR (Memory) );
  294.                   IF Count = LONGCARD (SIZE (Memory)) THEN
  295.                      FileStatus := GEMDOS.EOK;
  296.                   END;
  297.                END;
  298.             END;
  299.          END;
  300.          Success := GEMDOS.Close ( FileHandle );
  301.       END;
  302.       IF FileStatus <> GEMDOS.EOK THEN
  303.          FileSaveError := FileSaveErrorLine1;
  304.          Success       := Text.ConcatString ( FileSaveError, FileSaveErrorLine2, FileSaveError );
  305.          ExitButton    := AESForms.FormAlert ( 1, FileSaveError );
  306.       END;
  307.    END SaveProgram;
  308.  
  309.    (************************ LOCAL ROUTINE *****************************)
  310.  
  311.    PROCEDURE LoadProgram;
  312.  
  313.    CONST
  314.       Ok         = 1;
  315.       ReadWrite  = 2;
  316.  
  317.    VAR
  318.       Buffer       : Text.String80;
  319.       FullFileName : Text.String80;
  320.       ExitButton   : INTEGER;
  321.       FileHandle   : INTEGER;
  322.       FileStatus   : INTEGER;
  323.       Count        : LONGCARD;
  324.       Success      : BOOLEAN;
  325.       FileType     : String3;
  326.  
  327.    BEGIN
  328.       AESForms.FileSelectorInput (
  329.          ADR (Directory), ADR (FileNameBody), ExitButton );
  330.       Text.UpperCase ( Directory );
  331.       IF (ExitButton = Ok) AND (Text.Length (FileNameBody) > 0) THEN
  332.          ClearMemory;
  333.          FileName.BuildFileName ( Directory, FileNameBody, FullFileName );
  334.          IF FullFileName[1] = ':' THEN
  335.             Disk.CheckStatus ( ORD (FullFileName[0]) - ORD ('A') + 1 );
  336.          END;
  337.          FileStatus := GEMDOS.EOK;
  338.          GEMDOS.Open ( FullFileName, ReadWrite, FileHandle );
  339.          IF FileHandle < GEMDOS.EOK THEN
  340.             FileStatus := FileHandle;
  341.          ELSE
  342.             FileStatus := GEMDOS.EReadF;
  343.             Count := LONGCARD (SIZE (FileType));
  344.             GEMDOS.Read ( FileHandle, Count, ADR (FileType) );
  345.             IF Count = LONGCARD (SIZE (FileType)) THEN
  346.                IF Text.Compare ( FileType, FileSignature ) <> Text.Equal THEN
  347.                   ExitButton := AESForms.FormAlert ( 1, FileTypeError );
  348.                   FileStatus := GEMDOS.EOK;
  349.                ELSE
  350.                   Count := LONGCARD (SIZE (ProgramSize));
  351.                   GEMDOS.Read ( FileHandle, Count, ADR (ProgramSize) );
  352.                   IF Count = LONGCARD (SIZE (ProgramSize)) THEN
  353.                      Count := LONGCARD (SIZE (Memory));
  354.                      GEMDOS.Read ( FileHandle, Count, ADR (Memory) );
  355.                      IF Count = LONGCARD (SIZE (Memory)) THEN
  356.                         FileStatus := GEMDOS.EOK;
  357.                      END;
  358.                   END;
  359.                END;
  360.             END;
  361.          END;
  362.          Success := GEMDOS.Close ( FileHandle );
  363.          IF FileStatus = GEMDOS.EOK THEN
  364.             PC := 0;
  365.             GetStepText ( PC, Buffer );
  366.             Readout.Write ( Buffer, UpdateRegion );
  367.          ELSE
  368.             ExitButton := AESForms.FormAlert ( 1, FileLoadError );
  369.          END;
  370.       END;
  371.    END LoadProgram;
  372.  
  373.    (************************ LOCAL ROUTINE *****************************)
  374.  
  375.    PROCEDURE GoToAddress;
  376.  
  377.    VAR NewLocation : CARDINAL;
  378.  
  379.       PROCEDURE ConvertDigit ( Location : CARDINAL ) : CARDINAL;
  380.  
  381.       VAR Key : INTEGER;
  382.  
  383.       BEGIN
  384.          Key := Memory[Location];
  385.          IF Key = Resource.D9KEY0 THEN
  386.             RETURN (0);
  387.          ELSIF Key = Resource.D9KEY1 THEN
  388.             RETURN (1);
  389.          ELSIF Key = Resource.D9KEY2 THEN
  390.             RETURN (2);
  391.          ELSIF Key = Resource.D9KEY3 THEN
  392.             RETURN (3);
  393.          ELSIF Key = Resource.D9KEY4 THEN
  394.             RETURN (4);
  395.          ELSIF Key = Resource.D9KEY5 THEN
  396.             RETURN (5);
  397.          ELSIF Key = Resource.D9KEY6 THEN
  398.             RETURN (6);
  399.          ELSIF Key = Resource.D9KEY7 THEN
  400.             RETURN (7);
  401.          ELSIF Key = Resource.D9KEY8 THEN
  402.             RETURN (8);
  403.          ELSIF Key = Resource.D9KEY9 THEN
  404.             RETURN (9);
  405.          ELSE
  406.             RETURN (0);
  407.          END;
  408.       END ConvertDigit;
  409.  
  410.    BEGIN
  411.       NewLocation :=
  412.          (ConvertDigit ( PC )   * 100) +
  413.          (ConvertDigit ( PC+1 ) *  10) +
  414.          (ConvertDigit ( PC+2 ));
  415.       NewLocation := NewLocation MOD MemorySize;
  416.       PC := NewLocation;
  417.    END GoToAddress;
  418.  
  419.    (************************ LOCAL ROUTINE *****************************)
  420.  
  421.    PROCEDURE PrintProgram;
  422.  
  423.    VAR
  424.       Location : CARDINAL;
  425.       Buffer   : Text.String80;
  426.  
  427.    BEGIN
  428.       IF GEMDOS.PrnOS () THEN
  429.          FOR Location := 0 TO ProgramSize - 1 DO
  430.             GetStepText ( Location, Buffer );
  431.             Print.String ( Buffer );
  432.          END;
  433.       END;
  434.    END PrintProgram;
  435.  
  436.    (********************************************************************)
  437.  
  438.    PROCEDURE Initialize;
  439.  
  440.    VAR
  441.       Index   : CARDINAL;
  442.       Success : BOOLEAN;
  443.  
  444.    BEGIN
  445.       Text.Assign ( Configuration.DefaultDrive, Directory );
  446.       Index := Text.Length (Directory);
  447.       IF (Index > 0) AND (Directory[Index - 1] = '*') THEN
  448.          Directory[Index-1] := CHR (0);  (* Strip off the last asterisk *)
  449.          Success := Text.ConcatString ( Directory, "CAL", Directory );
  450.       END;
  451.       FileNameBody := DefaultFileName;
  452.    END Initialize;
  453.  
  454.    (********************************************************************)
  455.  
  456.    PROCEDURE ProcessKey (
  457.       VAR Key       : (* IN *) INTEGER;
  458.       WindowBorders : (* IN *) Screen.Box ) : BOOLEAN;
  459.  
  460.    CONST ShowKeys   = TRUE;
  461.  
  462.    VAR
  463.       Buffer          : Text.String80;
  464.       KeyWasProcessed : BOOLEAN;
  465.       Success         : BOOLEAN;
  466.       Number          : Text.String80;
  467.       Status          : Expression.CompareResult;
  468.       Index           : CARDINAL;
  469.       Ch              : CHAR;
  470.       Object          : Icon.ObjectPtr;
  471.  
  472.    BEGIN
  473.       UpdateRegion    := WindowBorders;
  474.       KeyWasProcessed := TRUE;
  475.  
  476.       IF ExpectKeys > 0 THEN
  477.          Success := Keypad.ProcessKey ( Key, UpdateRegion, ShowKeys, Number );
  478.          IF Keypad.ConvertKeyToCh ( Key, Ch ) AND (Ch >= '0') AND (Ch <= '9') THEN
  479.             InsertKey ( Key );
  480.             DEC (ExpectKeys);
  481.          ELSE
  482.             GEMDOS.ConOut ( Bell );
  483.          END;
  484.  
  485.       ELSIF Key = Resource.D9PGM THEN
  486.          IF EnteringSteps THEN
  487.             EnteringSteps := FALSE;
  488.          ELSE
  489.             EnteringSteps := TRUE;
  490.             GetStepText ( PC, Buffer );
  491.             Readout.Write ( Buffer, UpdateRegion );
  492.          END;
  493.          KeyWasProcessed := FALSE;
  494.  
  495.       ELSIF Key = Resource.D9SAVE THEN
  496.          SaveProgram;
  497.  
  498.       ELSIF Key = Resource.D9LOAD THEN
  499.          LoadProgram;
  500.  
  501.       ELSIF Key = Resource.D9GOTO THEN
  502.          IF EnteringSteps THEN
  503.             InsertKey ( Key );
  504.             ExpectKeys := 3;
  505.             Success    := Keypad.ProcessKey (
  506.                Key, UpdateRegion, ShowKeys, Number );
  507.          ELSE
  508.             GoToAddress;
  509.          END;
  510.  
  511.       ELSIF Key = Resource.D9EQLZER THEN
  512.          IF EnteringSteps THEN
  513.             InsertKey ( Key );
  514.             ExpectKeys := 3;
  515.             Success    := Keypad.ProcessKey (
  516.                Key, UpdateRegion, ShowKeys, Number );
  517.          ELSE
  518.             Expression.CompareTOS ( Status );
  519.             IF Status = Expression.EqualZero THEN
  520.                GoToAddress;
  521.             ELSE
  522.                INC (PC, 3);
  523.             END;
  524.          END;
  525.  
  526.       ELSIF Key = Resource.D9GTRZER THEN
  527.          IF EnteringSteps THEN
  528.             InsertKey ( Key );
  529.             ExpectKeys := 3;
  530.             Success    := Keypad.ProcessKey (
  531.                Key, UpdateRegion, ShowKeys, Number );
  532.          ELSE
  533.             Expression.CompareTOS ( Status );
  534.             IF Status = Expression.GreaterThanZero THEN
  535.                GoToAddress;
  536.             ELSE
  537.                INC (PC, 3);
  538.             END;
  539.          END;
  540.  
  541.       ELSIF Key = Resource.D9SST THEN
  542.          INC (PC);
  543.          IF PC >= ProgramSize THEN
  544.             GEMDOS.ConOut ( Bell );
  545.             PC := 0;
  546.          END;
  547.          GetStepText ( PC, Buffer );
  548.          Readout.Write ( Buffer, UpdateRegion );
  549.  
  550.       ELSIF Key = Resource.D9BST THEN
  551.          IF PC = 0 THEN
  552.             GEMDOS.ConOut ( Bell );
  553.             PC := ProgramSize-1;
  554.          ELSE
  555.             DEC (PC);
  556.          END;
  557.          GetStepText ( PC, Buffer );
  558.          Readout.Write ( Buffer, UpdateRegion );
  559.  
  560.       ELSIF Key = Resource.D9INS THEN
  561.          IF (ProgramSize = MemorySize) OR (PC = MemorySize-1) THEN
  562.             GEMDOS.ConOut ( Bell );
  563.          ELSE
  564.             FOR Index := (MemorySize-1) TO (PC+1) BY -1 DO
  565.                Memory[Index] := Memory[Index-1];
  566.             END;
  567.             INC (ProgramSize);
  568.             Memory[PC] := Nop;
  569.             GetStepText ( PC, Buffer );
  570.             Readout.Write ( Buffer, UpdateRegion );
  571.          END;
  572.  
  573.       ELSIF Key = Resource.D9DEL THEN
  574.          IF ProgramSize = 1 THEN
  575.             GEMDOS.ConOut ( Bell );
  576.          ELSE
  577.             IF PC < (ProgramSize-1) THEN
  578.                FOR Index := (PC+1) TO (MemorySize-1) DO
  579.                   Memory[Index-1] := Memory[Index];
  580.                END;
  581.                DEC (ProgramSize);
  582.                GetStepText ( PC, Buffer );
  583.                Readout.Write ( Buffer, UpdateRegion );
  584.             ELSE
  585.                GEMDOS.ConOut ( Bell );
  586.             END;
  587.          END;
  588.  
  589.       ELSIF (Key = Resource.D9STO) OR
  590.             (Key = Resource.D9RCL) OR
  591.             (Key = Resource.D9SUM) THEN
  592.          IF EnteringSteps THEN
  593.             InsertKey ( Key );
  594.             ExpectKeys := 1;
  595.             Success    := Keypad.ProcessKey ( Key, UpdateRegion, ShowKeys, Number );
  596.          ELSE
  597.             KeyWasProcessed := FALSE;
  598.          END;
  599.  
  600.       ELSIF (Key = Resource.D9DEC) OR
  601.             (Key = Resource.D9HEX) OR
  602.             (Key = Resource.D9OCT) OR
  603.             (Key = Resource.D9BIN) THEN
  604.          NumberBase := Key;
  605.          IF EnteringSteps THEN
  606.             InsertKey ( Key );
  607.             Success := Keypad.ProcessKey ( Key, UpdateRegion, ShowKeys, Number );
  608.          ELSE
  609.             KeyWasProcessed := FALSE;
  610.          END;
  611.  
  612.       ELSIF (Key = Resource.D9F1) OR
  613.             (Key = Resource.D9F2) OR
  614.             (Key = Resource.D9F3) OR
  615.             (Key = Resource.D9F4) OR
  616.             (Key = Resource.D9F5) OR
  617.             (Key = Resource.D9F6) OR
  618.             (Key = Resource.D9F7) OR
  619.             (Key = Resource.D9F8) OR
  620.             (Key = Resource.D9F9) OR
  621.             (Key = Resource.D9F10) THEN
  622.          IF EnteringSteps THEN
  623.             InsertKey ( Key );
  624.          ELSE
  625.             SearchKey ( Key );
  626.          END;
  627.  
  628.       ELSIF Key = Resource.D9RUN THEN
  629.          IF NOT EnteringSteps THEN
  630.             ExecuteProgram;
  631.          END;
  632.  
  633.       ELSIF Key = Resource.D9STOP THEN
  634.          IF EnteringSteps THEN
  635.             InsertKey ( Key );
  636.          END;
  637.  
  638.       ELSIF Key = Resource.D9PRINT THEN
  639.          IF EnteringSteps THEN
  640.             Object := Icon.GetAddress ( Resource.D9CALC, Resource.D9PRINT );
  641.             Object^.State := Object^.State + {Icon.Selected};
  642.             Icon.Display ( Resource.D9CALC, Resource.D9PRINT, UpdateRegion );
  643.             AESGraphics.GrafMouse ( GEMAESbase.HourGlass, NIL );
  644.             PrintProgram;
  645.             AESGraphics.GrafMouse ( GEMAESbase.Arrow, NIL );
  646.             Object^.State := Object^.State - {Icon.Selected};
  647.             Icon.Display ( Resource.D9CALC, Resource.D9PRINT, UpdateRegion );
  648.          END;
  649.  
  650.       ELSE
  651.          IF EnteringSteps THEN
  652.             InsertKey ( Key );
  653.          ELSE
  654.             KeyWasProcessed := FALSE;
  655.          END;
  656.       END;
  657.       RETURN (KeyWasProcessed);
  658.    END ProcessKey;
  659.  
  660. BEGIN
  661.    ClearMemory;
  662.    EnteringSteps := FALSE;
  663.    PC            := 0;
  664.    ExpectKeys    := 0;
  665.    FileSignature := "SMN";
  666. END Program.
  667.  
  668.